package com.bdd.service.Impl;

import com.bdd.Enum.DiscountEnum;
import com.bdd.entity.*;
import com.bdd.mapper.*;
import com.bdd.model.bo.clothing.ClothingBO;
import com.bdd.model.bo.clothing.ClothingAddBO;
import com.bdd.service.ClothingService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ClothingServiceImpl implements ClothingService {

    @Autowired
    ClothingDao clothingDao;

    @Autowired
    ClothingSizeDao clothingSizeDao;

    @Autowired
    InventoryDao inventoryDao;

    @Autowired
    SizeDao sizeDao;

    @Autowired
    ClothingDiscountDao clothingDiscountDao;

    @Autowired
    DiscountDao discountDao;

    @Override
    public Page<ClothingBO> list(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        Page<ClothingBO> boList = clothingDao.selectBOList();
        for (ClothingBO clothingBO:boList.getResult()){
            if (!Objects.isNull(clothingBO.getDiscounts())){
                clothingBO.setNewPrice(clothingBO.getPrice() * DiscountEnum.getDiscountByName(clothingBO.getDiscounts()));
            }else
                clothingBO.setNewPrice(clothingBO.getPrice());
        }
        return boList;
    }

    @Override
    @Transactional
    public void add(ClothingAddBO bo) {
        //插入服装表
        Clothing clothing = ClothingMapUtil.AddBoToDo(bo);
        clothingDao.insert(clothing);

        //插入规格表
        String sizeStr = bo.getSize();
        Size size = sizeDao.selectBySpecs(sizeStr);
        if (ObjectUtils.isEmpty(size)) {
            size = Size.builder()
                    .specs(sizeStr)
                    .build();
            sizeDao.insertSelective(size);
        }
        ClothingSize clothingSize = ClothingSize.builder()
                .clothingId(clothing.getId())
                .sizeId(size.getId())
                .build();
        clothingSizeDao.insertSelective(clothingSize);

        //更新库存
        Inventory inventory = inventoryDao.selectByCothingIdAndSizeId(clothing.getId(), size.getId());
        if (Objects.isNull(inventory)) {
            inventory = Inventory.builder()
                    .cothingId(clothing.getId())
                    .sizeId(size.getId())
                    .quantity(bo.getQuantity())
                    .build();
            inventoryDao.insertSelective(inventory);
        } else {
            inventory.setQuantity(inventory.getQuantity() + bo.getQuantity());
            inventoryDao.updateByPrimaryKey(inventory);
        }

        //更新clothing_discount
        Discount discount = discountDao.selectByPromotionName(bo.getPromotionName());
        if (!Objects.isNull(discount)){
            ClothingDiscount clothingDiscount = ClothingDiscount.builder()
                    .clothingId(clothing.getId())
                    .discountId(discount.getId())
                    .startTime(discount.getStartTime())
                    .endTime(discount.getEndTime())
                    .build();
            clothingDiscountDao.insert(clothingDiscount);
        }
    }

    @Override
    @Transactional
    public void edit(ClothingBO bo) {
        Clothing clothing = ClothingMapUtil.boToDo(bo);
        if (!clothingIsEmpty(clothing)) {
            clothingDao.updateByPrimaryKeySelective(clothing);
        }
        //插入规格表
        if (!Objects.isNull(bo.getSize())) {
            Size size = sizeDao.selectBySpecs(bo.getSize());
            if (Objects.isNull(size)) {
                size = Size.builder()
                        .specs(bo.getSize())
                        .build();
                sizeDao.insertSelective(size);
            }
            ClothingSize clothingSize = ClothingSize.builder()
                    .clothingId(clothing.getId())
                    .sizeId(size.getId())
                    .build();
            clothingSizeDao.updateByPrimaryKeySelective(clothingSize);
        }

        //更新库存
        if (bo.getQuantity()!=0) {
            Inventory inventory = Inventory.builder()
                    .cothingId(clothing.getId())
                    .sizeId(bo.getSizeId())
                    .quantity(bo.getQuantity())
                    .build();
            inventoryDao.updateByPrimaryKeySelective(inventory);
        }

        //更新clothing_discount
        Discount discount = discountDao.selectByPromotionName(bo.getPromotionName());
        if (!Objects.isNull(discount)){
            if (clothingDiscountDao.selectClothingDiscount(bo.getId()) != null){
                ClothingDiscount clothingDiscount = clothingDiscountDao.selectClothingDiscount(bo.getId());
                clothingDiscount.setDiscountId(discount.getId());
                clothingDiscount.setStartTime(discount.getStartTime());
                clothingDiscount.setEndTime(discount.getEndTime());
                clothingDiscountDao.updateByPrimaryKey(clothingDiscount);
            }else{
                ClothingDiscount clothingDiscount = ClothingDiscount.builder()
                        .clothingId(bo.getId())
                        .discountId(discount.getId())
                        .startTime(discount.getStartTime())
                        .endTime(discount.getEndTime())
                        .build();
                clothingDiscountDao.insert(clothingDiscount);
            }
        }

    }

    private boolean clothingIsEmpty(Clothing clothing) {
        boolean flag = true;
        flag = StringUtils.isEmpty(clothing.getName()) && Objects.isNull(clothing.getCateId())
                && Objects.isNull(clothing.getPrice());
        return flag;

    }

    @Override
    public void delete(Integer id) {
        clothingDao.deleteByPrimaryKey(id);
        clothingDiscountDao.deleteByClothingId(id);
    }

    @Override
    public List<ClothingBO> searchByName(String name) {
        List<ClothingBO> boList = clothingDao.searchByName(name);
        return boList;
    }

    static class ClothingMapUtil {

        static List<ClothingBO> dolisttobolist(List<Clothing> clothingList) {
            List<ClothingBO> bOtList = clothingList.stream().map(clothing -> {
                ClothingBO bo = ClothingBO.builder()
                        .id(clothing.getId())
                        .name(clothing.getName())
                        .cateId(clothing.getCateId())
                        .build();
                return bo;
            }).collect(Collectors.toList());
            return bOtList;
        }

        static Clothing AddBoToDo(ClothingAddBO bo) {
            Clothing clothing = Clothing.builder()
                    .name(bo.getName())
                    .price(bo.getPrice())
                    .cateId(bo.getCateId())
                    .build();
            return clothing;
        }

        static Clothing boToDo(ClothingBO bo) {
            Clothing clothing = Clothing.builder()
                    .id(bo.getId())
                    .name(bo.getName())
                    .price(bo.getPrice())
                    .build();
            return clothing;
        }

    }
}
